package br.com.petsis.session;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;

import br.com.petsis.entity.Funcionalidade;
import br.com.petsis.entity.PerfilFuncionalidade;
import br.com.petsis.entity.Usuario;
import br.com.petsis.utilitarios.UtilDate;
import br.com.petsis.utilitarios.UtilString;

@Name("authenticator")
public class Authenticator
{
	private static final String QRY_USUARIO = "select u from Usuario u where u.dscUsuario = :dscUsuario and u.flgAtivo = 'T' ";
	private static final String QRY_PERFIL = "select pf from PerfilFuncionalidade pf where pf.perfil.idPerfil = :idPerfil";
	private static final String QRY_FUNCIONALIDADE = "select f from Funcionalidade f where f.flgAtivo = 'T'";
	private static final String PARAMETER_DSC_USUARIO = "dscUsuario";
	private static final String SENHA_ADMIN = "Ami2012";
	
    @Logger private Log log;

    @In Identity identity;
    @In Credentials credentials;
    @In(create=true)
    private EntityManager entityManager;
    
    @Out(scope=ScopeType.SESSION, required=false)
    private Usuario usuarioLogado;

	public boolean authenticate()
    {
    	try{
    		Usuario user = (Usuario)entityManager.createQuery(QRY_USUARIO)
    			.setParameter(PARAMETER_DSC_USUARIO, credentials.getUsername())
    			.getSingleResult();
    		if(user.getDscSenha().equals(UtilString.md5(credentials.getPassword()))){
    			log.info("authenticating {0}", credentials.getUsername());
    			usuarioLogado = user;
    			addRolesUser();
                return true;
    		}
    	}catch(NoResultException e){
    		if(credentials.getUsername().equals("admin")
    				&& credentials.getPassword().equals(SENHA_ADMIN)){
    			identity.addRole("admin");
    			usuarioLogado = new Usuario();
    			usuarioLogado.setDscNome(credentials.getUsername());
    			usuarioLogado.setDscUsuario(credentials.getUsername());
    			usuarioLogado.setDtaUltimoAcesso(UtilDate.getDataAtual());
    			List<Funcionalidade> funcionalidades = entityManager.createQuery(QRY_FUNCIONALIDADE).getResultList();
    			for(Funcionalidade f : funcionalidades){
    				identity.addRole(f.getDscDescricao()+"_LER");
    				identity.addRole(f.getDscDescricao()+"_GRAVAR");
    				identity.addRole(f.getDscDescricao()+"_EXCLUIR");
    				identity.addRole(f.getDscDescricao()+"_DESCONTO");
    			}
    			return true;
    		}else{
    			try{
    				Usuario user = (Usuario)entityManager
    					.createQuery("select u from Usuario u where UPPER(u.cliente.dscEmail) = UPPER(:email)")
    					.setParameter("email", credentials.getUsername())
    					.getSingleResult();
    				if(user.getDscSenha().equals(UtilString.md5(credentials.getPassword()))){
    					log.info("authenticating {0}", credentials.getUsername());
    					usuarioLogado = user;
    					addRolesUser();
    					return true;
    				}
    			}catch (NoResultException n) {
    				return false;
				}
    		}
    		return false;
    	}
        
        return false;
    }
	
	private void addRolesUser(){
		List<PerfilFuncionalidade> permissoes = entityManager.createQuery(QRY_PERFIL)
			.setParameter("idPerfil", usuarioLogado.getPerfil().getIdPerfil())
			.getResultList();
		for(PerfilFuncionalidade pf : permissoes){
			if(pf.getFlgLeitura().equals('T')){
				identity.addRole(pf.getFuncionalidade().getDscDescricao()+"_LER");
			}
			if(pf.getFlgGravacao().equals('T')){
				identity.addRole(pf.getFuncionalidade().getDscDescricao()+"_GRAVAR");
			}
			if(pf.getFlgExclusao().equals('T')){
				identity.addRole(pf.getFuncionalidade().getDscDescricao()+"_EXCLUIR");
			}
			if(pf.getFlgDesconto().equals('T')){
				identity.addRole(pf.getFuncionalidade().getDscDescricao()+"_DESCONTO");
			}
		}
	}
    
}
